package cn.monkey.transport.netty.server.codec.protocol.tcp.http;

import cn.monkey.transport.netty.utils.ChannelHandlerUtils;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

import javax.net.ssl.SSLEngine;
import java.util.function.Consumer;

public interface HttpServerProtocolConsumer extends Consumer<Channel> {

    HttpServerProtocolConsumer INSTANCE = HttpServerProtocolConfig::defaultConfig;

    HttpServerProtocolConfig httpServerProtocolConfig();

    @Override
    default void accept(Channel channelHandlerContext) {
        ChannelPipeline pipeline = channelHandlerContext.pipeline();
        HttpServerProtocolConfig httpServerProtocolConfig = this.httpServerProtocolConfig();
        SslContext sslContext = httpServerProtocolConfig.getSslContext();
        if (sslContext != null) {
            SSLEngine sslEngine = sslContext.newEngine(ByteBufAllocator.DEFAULT);
            pipeline.addLast(new SslHandler(sslEngine));
        }
        pipeline.addLast(ChannelHandlerUtils.normalizeName(HttpServerCodec.class), new HttpServerCodec(httpServerProtocolConfig.getMaxInitialLineLength(), httpServerProtocolConfig.getMaxHeaderSize(), httpServerProtocolConfig.getMaxChunkSize()))
                .addLast(ChannelHandlerUtils.normalizeName(ChunkedWriteHandler.class), new ChunkedWriteHandler())
                .addLast(ChannelHandlerUtils.normalizeName(HttpObjectAggregator.class), new HttpObjectAggregator(httpServerProtocolConfig.getMaxContentLength(), httpServerProtocolConfig.isCloseOnExpectationFailed()));
    }
}
